package controller

import (
	"gitee.com/saxon134/sysmain/api"
	"gitee.com/saxon134/sysmain/db"
	"gitee.com/saxon134/sysmain/db/models"
	"gitee.com/saxon134/sysmain/errs"
	"github.com/saxon134/go-utils/saData/saTime"
	"github.com/saxon134/go-utils/saData/saUrl"
	"net/http"
	"sort"
	"time"
)

type OverviewItem struct {
	Fail    int `json:"fail"`
	Success int `json:"success"`
}

// ApiOverview 接口概览，返回当日/昨日接口总数据
func ApiOverview(w http.ResponseWriter, r *http.Request) {
	var now = time.Now()
	var start, end string
	var err error

	sql := `
		SELECT
			sum( success ) success,
			sum( fail ) fail
		FROM
			stats_api 
		WHERE
			ts >= ? 
		AND
			ts < ?
	`

	var today = new(OverviewItem)
	start = saTime.TimeToStr(time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()), "2006010200")
	end = saTime.TimeToStr(now, "2006010200")
	err = db.MySql.Table(models.TBNStatsApi).Raw(sql, start, end).Scan(today).Error
	if db.MySql.IsError(err) {
		api.ResError(w, err.Error())
		return
	}

	var yesterday = new(OverviewItem)
	now = now.Add(time.Hour * -24)
	start = saTime.TimeToStr(time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()), "2006010200")
	end = saTime.TimeToStr(now, "2006010200")
	err = db.MySql.Table(models.TBNStatsApi).Raw(sql, start, end).Scan(yesterday).Error
	if db.MySql.IsError(err) {
		api.ResError(w, err.Error())
		return
	}

	api.ResSuccess(w, map[string]map[string]interface{}{
		"today": {
			"success": today.Success,
			"fail":    today.Fail,
		},
		"yesterday": {
			"success": yesterday.Success,
			"fail":    yesterday.Fail,
		},
	})
}

// ApiList 接口列表，按照调用次数倒序排序，指定时间范围内调用次数会汇总
func ApiList(w http.ResponseWriter, r *http.Request) {
	offset, limit := api.Paging(r)
	var start, end string
	var now = time.Now()

	var str = saUrl.QueryDecode(r.URL.Query().Get("start"))
	if str != "" {
		start = saTime.TimeToStr(saTime.TimeFromStr(start, saTime.FormatDefault), saTime.FormatDefault)
	}
	if start == "" {
		start = saTime.TimeToStr(time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()), saTime.FormatDefault)
	}

	str = saUrl.QueryDecode(r.URL.Query().Get("end"))
	if str != "" {
		end = saTime.TimeToStr(saTime.TimeFromStr(end, saTime.FormatDefault), saTime.FormatDefault)
	}
	if end == "" {
		end = saTime.TimeToStr(now, saTime.FormatDefault)
	}

	var query = r.URL.Query()
	conn := db.MySql.Table(models.TBNStatsApi).Where("ts >= ?", start).Where("ts < ?", end)

	var app = query.Get("app")
	if app != "" {
		conn.Where("app = ?", app)
	}

	var key = query.Get("key")
	if key != "" {
		conn.Where("`key` = ?", key)
	}

	var path = query.Get("path")
	if path != "" {
		conn.Where("path like '%?%'", path)
	}

	var total int64
	conn.Count(&total)
	if total <= int64(offset) {
		api.ResSuccess(w, nil, total)
		return
	}

	var ary = make([]*models.TblStatsApi, 0, limit)
	err := conn.Limit(limit).Offset(offset).Find(&ary).Error
	if db.MySql.IsError(err) {
		api.ResError(w, err.Error())
		return
	}

	sort.Slice(ary, func(i, j int) bool {
		return ary[i].Success+ary[i].Fail >= ary[j].Success+ary[j].Fail
	})
	api.ResSuccess(w, ary, total)
}

// ApiIntervalList 接口时段数据，指定接口查看时段数据
func ApiIntervalList(w http.ResponseWriter, r *http.Request) {
	var start, end string
	var now = time.Now()

	var str = saUrl.QueryDecode(r.URL.Query().Get("start"))
	if str != "" {
		start = saTime.TimeToStr(saTime.TimeFromStr(start, saTime.FormatDefault), saTime.FormatDefault)
	}
	if start == "" {
		start = saTime.TimeToStr(time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()), saTime.FormatDefault)
	}

	str = saUrl.QueryDecode(r.URL.Query().Get("end"))
	if str != "" {
		end = saTime.TimeToStr(saTime.TimeFromStr(end, saTime.FormatDefault), saTime.FormatDefault)
	}
	if end == "" {
		end = saTime.TimeToStr(now, saTime.FormatDefault)
	}

	var query = r.URL.Query()
	conn := db.MySql.Table(models.TBNStatsApi).Where("ts >= ?", start).Where("ts < ?", end)

	var app = query.Get("app")
	if app == "" {
		api.ResError(w, errs.ErrorParams.Error())
		return
	}
	conn.Where("app = ?", app)

	var path = query.Get("path")
	if path == "" {
		api.ResError(w, errs.ErrorParams.Error())
		return
	}
	conn.Where("path = ?", path)

	var key = query.Get("key")
	if key != "" {
		conn.Where("`key` = ?", key)
	} else {
		conn.Where("`key` is null")
	}

	var ary = make([]*models.TblStatsApi, 0, 30)
	err := conn.Group("ts").Order("ts desc").Find(&ary).Error
	if db.MySql.IsError(err) {
		api.ResError(w, err.Error())
		return
	}

	api.ResSuccess(w, ary)
}
